<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>子查询表达式</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="functions-aggregate.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="functions.html">快退</a></td><td width="60%" align="center" valign="bottom">章9. 函数和操作符</td><td width="10%" align="right" valign="top"><a href="functions.html">快进</a></td><td width="10%" align="right" valign="top"><a href="functions-comparisons.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="FUNCTIONS-SUBQUERY">9.16. 子查询表达式</a></h1><a name="AEN13868"></a><a name="AEN13870"></a><a name="AEN13872"></a><a name="AEN13874"></a><a name="AEN13876"></a><a name="AEN13878"></a><a name="AEN13880"></a>
<p>本节描述 PostgreSQL 里面与 SQL 兼容的子查询表达式。所有本节中的表达式都返回布尔值(真/假)结果。</p>
<div class="SECT2"><h2 class="SECT2"><a name="AEN13885">9.16.1. <tt class="LITERAL">EXISTS</tt></a></h2>
<pre class="SYNOPSIS">EXISTS (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p><tt class="TOKEN">EXISTS</tt> 的参数是一个任意的 <tt class="COMMAND">SELECT</tt> 语句，或者说<i class="FIRSTTERM">子查询</i>。系统对子查询进行运算以判断它是否返回行。如果它至少返回一行，那么 <tt class="TOKEN">EXISTS</tt> 的结果就为"真"；如果子查询没有返回任何行，那么 <tt class="TOKEN">EXISTS</tt> 的结果是"假"。</p>
<p>子查询可以引用包围它的查询的变量，这些变量在该子查询的每一次计算中都起常量的作用。</p>
<p>这个子查询通常只是运行到能判断它是否可以生成至少一行为止，而不是等到全部结束。在这里写任何有副作用的子查询都是不明智的(比如调用序列函数)；这些副作用是否发生是很难判断的。</p>
<p>因为结果只取决于是否会返回行，而不取决于这些行的内容，所以这个子查询的输出列表通常是无关紧要的。一个常用的编码习惯是用下面的形式写 <tt class="LITERAL">EXISTS</tt> 测试：<tt class="LITERAL">EXISTS(SELECT 1 WHERE ...)</tt> 。不过这条规则也有例外，比如那些使用 <tt class="TOKEN">INTERSECT</tt> 的子查询。</p>
<p>下面这个简单的例子类似在 <tt class="LITERAL">col2</tt> 上的一次内连接，但是它为每个 <tt class="LITERAL">tab1</tt> 的行生成最多一个输出，即使存在多个匹配 <tt class="LITERAL">tab2</tt> 的行也如此：</p>
<pre class="SCREEN">SELECT col1 FROM tab1
    WHERE EXISTS(SELECT 1 FROM tab2 WHERE col2 = tab1.col2);</pre>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN13909">9.16.2. <tt class="LITERAL">IN</tt></a></h2>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>expression</i></tt> IN (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>右边是一个圆括弧括起来的子查询，它必须只返回一个字段。左边表达式对子查询结果的每一行进行一次计算和比较。如果找到任何相等的子查询行，则 <tt class="TOKEN">IN</tt> 结果为"真"。如果没有找到任何相等行，则结果为"假"(包括子查询没有返回任何行的情况)。</p>
<p>请注意，如果左边表达式的值为 NULL ，或者没有相等的右边值并且至少有一个右边行生成 NULL ，那么 <tt class="TOKEN">IN</tt> 的结果将是 NULL ，而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。</p>
<p>和 <tt class="TOKEN">EXISTS</tt> 一样，假设子查询将被完全运行是不明智的。</p>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>row_constructor</i></tt> IN (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>左边是一个行构造器(如<a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">节4.2.11</a>所述)，右边是一个圆括弧括起来的子查询，它必须返回和左边行构造器一样多的字段。左边表达式对子查询结果的每一行进行一次计算和比较。如果找到相等的子查询行，则 <tt class="TOKEN">IN</tt> 结果为"真"。如果没有找到任何相等行，则结果为"假"(包括子查询没有返回任何行的情况)。</p>
<p>表达式或子查询行里的 NULL 遵照 SQL 处理布尔值和 NULL 组合时的规则。如果两个行对应的字段都相等且非空，那么这两行相等；如果任意对应字段不等且非空，那么这两行不等；否则结果是未知(NULL)。如果每一行的结果都是不等或 NULL ，并且至少有一个 NULL ，那么 <tt class="TOKEN">IN</tt> 的结果是 NULL 。</p>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN13934">9.16.3. <tt class="LITERAL">NOT IN</tt></a></h2>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>expression</i></tt> NOT IN (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>右边是一个圆括弧括起来的子查询，它必须只返回一个字段。左边表达式对子查询结果的每一行进行一次计算和比较。如果只找到不相等的子查询行(包括子查询没有返回任何行的情况)，则 <tt class="TOKEN">NOT IN</tt> 结果为"真"。如果找到任何相等行，则结果为"假"。</p>
<p>请注意，如果左边表达式的值为 NULL ，或者没有相等的右边值并且至少有一个右边行生成 NULL ，那么 <tt class="TOKEN">NOT IN</tt> 的结果将是 NULL ，而不是真。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。</p>
<p>和 <tt class="TOKEN">EXISTS</tt> 一样，假设子查询将被完全运行是不明智的。</p>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>row_constructor</i></tt> NOT IN (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>左边是一个行构造器(如<a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">节4.2.11</a>所述)，右边是一个圆括弧括起来的子查询，它必须返回和左边行构造器一样多的字段。左边表达式对子查询结果的每一行进行一次计算和比较。如果只出现不相等的子查询行，则 <tt class="TOKEN">NOT IN</tt> 结果为"真"。(包括子查询没有返回任何行的情况)。如果找到相等的子查询行，则结果为"假"。</p>
<p>表达式或子查询行里的 NULL 遵照 SQL 处理布尔值和 NULL 组合时的规则。如果两个行对应的字段都相等且非空，那么这两行相等；如果任意对应字段不等且非空，那么这两行不等；否则结果是未知(NULL)。如果每一行的结果都是不等或 NULL ，并且至少有一个 NULL ，那么 <tt class="TOKEN">NOT IN</tt> 的结果是 NULL 。</p>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN13959">9.16.4. <tt class="LITERAL">ANY</tt>/<tt class="LITERAL">SOME</tt></a></h2>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>expression</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> ANY (<tt class="REPLACEABLE"><i>subquery</i></tt>)
<tt class="REPLACEABLE"><i>expression</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> SOME (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>右边是一个圆括弧括起来的子查询，它必须只返回一个字段。左边表达式使用 <tt class="REPLACEABLE"><i>operator</i></tt> 对子查询结果的每一行进行一次计算和比较，其结果必须是布尔值。如果至少获得一个真值，则 <tt class="TOKEN">ANY</tt> 结果为"真"。如果全部获得假值，则结果是"假"(包括子查询没有返回任何行的情况)。</p>
<p><tt class="TOKEN">SOME</tt> 是 <tt class="TOKEN">ANY</tt> 的同意词。<tt class="TOKEN">IN</tt> 等效于 <tt class="LITERAL">= ANY</tt> 。</p>
<p>请注意，如果没有获得任何真值并且至少有一个右边行在该操作符上生成 NULL ，那么 <tt class="TOKEN">ANY</tt> 的结果将是 NULL ，而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。</p>
<p>和 <tt class="TOKEN">EXISTS</tt> 一样，假设子查询将被完全运行是不明智的。</p>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>row_constructor</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> ANY (<tt class="REPLACEABLE"><i>subquery</i></tt>)
<tt class="REPLACEABLE"><i>row_constructor</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> SOME (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>左边是一个行构造器(如<a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">节4.2.11</a>所述)，右边是一个圆括弧括起来的子查询，它必须返回和左边行构造器一样多的字段。左边表达式使用 <tt class="REPLACEABLE"><i>operator</i></tt> 对子查询结果的每一行进行一次计算和比较，其结果必须是布尔值。如果至少获得一个真值，则 <tt class="TOKEN">ANY</tt> 结果为"真"。如果全部获得假值，则结果是"假"(包括子查询没有返回任何行的情况)。</p>
<p>请注意，如果没有获得任何真值并且至少有一个右边行在该操作符上生成 NULL ，那么 <tt class="TOKEN">ANY</tt> 的结果将是 NULL ，而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。</p>
<p>查看<a href="functions-comparisons.html#ROW-WISE-COMPARISON">节9.17.5</a>获取关于逐行比较的细节。</p>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN14000">9.16.5. <tt class="LITERAL">ALL</tt></a></h2>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>expression</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> ALL (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>右边是一个圆括弧括起来的子查询，它必须只返回一个字段。左边表达式使用 <tt class="REPLACEABLE"><i>operator</i></tt> 对子查询结果的每一行进行一次计算和比较，其结果必须是布尔值。如果全部获得真值，<tt class="TOKEN">ALL</tt> 结果为"真"(包括子查询没有返回任何行的情况)。如果至少获得一个假值，则结果是"假"。</p>
<p>请注意，如果没有获得任何假值并且至少有一个右边行在该操作符上生成 NULL ，那么 <tt class="TOKEN">ALL</tt> 的结果将是 NULL ，而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。</p>
<p><tt class="TOKEN">NOT IN</tt> 等效于 <tt class="LITERAL">&lt;&gt; ALL</tt> 。</p>
<p>和 <tt class="TOKEN">EXISTS</tt> 一样，假设子查询将被完全运行是不明智的。</p>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>row_constructor</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> ALL (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>左边是一个行构造器(如<a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">节4.2.11</a>所述)，右边是一个圆括弧括起来的子查询，它必须返回和左边行构造器一样多的字段。左边表达式使用 <tt class="REPLACEABLE"><i>operator</i></tt> 对子查询结果的每一行进行一次计算和比较，其结果必须是布尔值。如果全部获得真值，<tt class="TOKEN">ALL</tt> 结果为"真"(包括子查询没有返回任何行的情况)。如果至少获得一个假值，则结果是"假"。</p>
<p>请注意，如果没有获得任何假值并且至少有一个右边行在该操作符上生成 NULL ，那么 <tt class="TOKEN">ALL</tt> 的结果将是 NULL ，而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。</p>
<p>查看<a href="functions-comparisons.html#ROW-WISE-COMPARISON">节9.17.5</a>以获取关于逐行比较的细节。</p>
</div>
<div class="SECT2"><h2 class="SECT2"><a name="AEN14030">9.16.6. 逐行比较</a></h2><a name="AEN14032"></a>
<pre class="SYNOPSIS"><tt class="REPLACEABLE"><i>row_constructor</i></tt> <tt class="REPLACEABLE"><i>operator</i></tt> (<tt class="REPLACEABLE"><i>subquery</i></tt>)</pre>
<p>左边是一个行构造器(如<a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">节4.2.11</a>所述)，右边是一个圆括弧括起来的子查询，它必须返回和左边行构造器一样多的字段。而且，该子查询不能返回超过 1 行结果(返回零行相当于 NULL)。左边表达式对子查询的唯一结果行进行计算和比较。</p>
<p>查看<a href="functions-comparisons.html#ROW-WISE-COMPARISON">节9.17.5</a>以获取关于逐行比较的细节。</p>
</div>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="functions-aggregate.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="functions-comparisons.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">聚集函数</td><td width="34%" align="center" valign="top"><a href="functions.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">行和数组比较</td></tr>
</table>
</div>
</body></html>